package com.xxl.job.executor.service.jobhandler;

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.executor.dao.QxWeatherMapper;
import com.xxl.job.executor.model.QxWeather;
import com.xxl.job.executor.utils.CmUtil;
import com.xxl.job.executor.utils.ConstUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.text.SimpleDateFormat;
import java.util.*;

/*
"天气数据（未来一周）抓取";
 */

@Component
public class WeatherDataFor7daysTask {

    private static Logger logger = LoggerFactory.getLogger(WeatherDataFor7daysTask.class);

    private String taskContents;
    @Autowired
    private ConstUtil constUtil;
    @Autowired
    private QxWeatherMapper qxWeatherMapper;

    @XxlJob(value = "WeatherDataFor7daysTask",init = "init", destroy = "destroy")
    public ReturnT<String> WeatherDataFor7daysTask(String param) throws Exception {


//        if (constUtil == null) {
//            constUtil = SpringContextHolder.getBean(ConstUtil.class);
//        }
//        if (qxWeatherMapper == null) {
//            qxWeatherMapper = SpringContextHolder.getBean(QxWeatherMapper.class);
//        }
        String weatherUrl = "";
        HashMap<String,String> district = new HashMap<>();
        district.put(constUtil.distName,constUtil.distId);
//        district.put("崂山","101120202");
//        district.put("市南","101120203");
//        district.put("即墨","101120204");
//        district.put("胶州","101120205");
//        district.put("黄岛","101120206");
//        district.put("莱西","101120207");
//        district.put("平度","101120208");
//        district.put("市北","101120209");
//        district.put("李沧","101120210");
//        district.put("城阳","101120211");
//          district.put("乌鲁木齐","101130101");
        // 青岛市天气数据网址前缀
        String weatherBaseUrl = constUtil.weatherBaseUrl1;
        // 循环获取各区市天气数据
        //        String szContent = openFile( "F:/ceshiHtml/weather.html");
        //        Parser parser = Parser.createParser(szContent, "utf-8");
        // 修改 无效Map Iterator
        Iterator<Map.Entry<String, String>> iterator  = district.entrySet().iterator();
        Map.Entry<String, String> entry = null;
        while (iterator.hasNext()) {
            entry = iterator.next();
            String key = entry.getKey();
            weatherUrl = weatherBaseUrl+district.get(key)+".shtml";
            // 获取html文本内容
            Document doc = getHtml(weatherUrl, constUtil);
            if (doc == null) {
                System.out.println("null");
            };
            // 获取地区
            String dist = doc.select("[class=crumbs fl]").select("span").last().text();
            // 获取当天日期
            String nowDateString = doc.select("[id=fc_24h_internal_update_time]").attr("value");
            String nowDate = nowDateString.substring(0, 4) + "-" + nowDateString.substring(4, 6)
                    + "-" + nowDateString.substring(6, 8);
            // 获取数据更新时间
            String updateTime = doc.select("[id=update_time]").attr("value");
            // 获取一周天气数据
            Elements liEle = doc.select("[class=t clearfix]").select("li");
            for (int i=0;i<liEle.size();i++) {
                QxWeather qxWeather;
                try{
                    SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
                    // 当天日期
                    Date date = df.parse(nowDate);
                    // 未来七天的日期
                    String wDate = df.format(new Date(date.getTime() + (long)i * 24 * 60 * 60 * 1000));
                    // 获取天气、温度、风速
                    String[] arr = liEle.get(i).select("p").text().split(" ");
                    // 获取七天中的天气数据
                    ArrayList<String> weatherList = new ArrayList<>();
                    String maxTemp = "";
                    String minTemp = "";
                    String todayInfo = "";
                    String []arr1 = arr[1].split("/");
                    if (i == 0) {
                        todayInfo = doc.select("[id=hidden_title]").attr("value");
                        String arr2 = todayInfo.substring(todayInfo.lastIndexOf("  ")+2);
                        String []temp = arr2.split("/");
                        maxTemp = temp[0];
                        minTemp = temp[1].substring(0,temp[1].indexOf("°C"));
                    }else{
                        if (arr1.length==2) {
                            // 最高温
                            if (arr1[0].length()>0) {
                                if (arr1[0].contains("℃")) {
                                    maxTemp = arr1[0].substring(0, arr1[0].length()-1);
                                    weatherList.add(maxTemp);
                                }else {
                                    maxTemp = arr1[0];
                                    weatherList.add(maxTemp);
                                }
                            }
                            // 最低温
                            if (arr1[1].length()>0) {
                                if (arr1[1].contains("℃")) {
                                    minTemp = arr1[1].substring(0, arr1[1].length()-1);
                                    weatherList.add(minTemp);
                                }else {
                                    minTemp = arr1[1];
                                    weatherList.add(minTemp);
                                }
                            }
                        }
                    }
                    // 天气
                    weatherList.add(arr[0]);
                    // 风速
                    weatherList.add(arr[2]);
                    // 获取风向1
                    String winElement1 = liEle.get(i).select("em").select("span").first().attr("title");
                    // 获取风向2
                    String winElement2 = liEle.get(i).select("em").select("span").last().attr("title");
                    // 风向
                    weatherList.add(winElement1.equals(winElement2) ? winElement1 : winElement1 + "转" + winElement2);
                    // 查询此日期天气数据（未来7天）是否存在
                    String urbanDistrict = key;
                    String wKind = "7d";
                    qxWeather = qxWeatherMapper.select7Days(wDate,wKind,urbanDistrict);
                    if(qxWeather==null){
                        // 不存在，插入一条新数据
                        try{
                            qxWeather = new QxWeather();
                            qxWeather.setId(CmUtil.getUUID());
                            qxWeather.setCreateTime(CmUtil.date2db(null));
                            qxWeather.setWdate(wDate);
                            qxWeather.setWtime(updateTime);
                            // 地区
                            qxWeather.setDist(key);
//                        // 获取天气、温度、风速
//                        String[] arr = liEle.get(i).select("p").text().split(" ");
                            // 天气
                            qxWeather.setSkyCondition(arr[0]);
                            // 最高温
                            qxWeather.setMaxTemp(maxTemp);
                            // 最低温
                            qxWeather.setMinTemp(minTemp);
                            // 风速
                            qxWeather.setWindSpeed(arr[2]);
//                        // 获取风向1
//                        String winElement1 = liEle.get(i).select("em").select("span").first().attr("title");
//                        // 获取风向2
//                        String winElement2 = liEle.get(i).select("em").select("span").last().attr("title");
                            // 风向
                            qxWeather.setWindDirection(winElement1.equals(winElement2) ? winElement1 : winElement1 + "转" + winElement2);
                            // 时间间隔
                            qxWeather.setPeriod(i+"");
                            // 数据类型(7days)
                            qxWeather.setWkind("7d");
                            qxWeather.setCreateTime(CmUtil.date2db(null));
                            // 存入数据库
                            qxWeatherMapper.insertSelective(qxWeather);
                            this.taskContents = "插入"+dist+" "+wDate+" "+"天气数据成功！";
                        }catch (Exception e){
                            e.printStackTrace();
                            this.taskContents = "插入"+dist+" "+wDate+" "+"天气数据异常！";
                        }
                    }else if(!qxWeather.toString1().equals(weatherList.toString())){
                        // 更新已有数据
                        try{
                            // 天气
                            qxWeather.setSkyCondition(arr[0]);
                            // 最高温
                            qxWeather.setMaxTemp(maxTemp);
                            // 最低温
                            qxWeather.setMinTemp(minTemp);
                            // 风速
                            qxWeather.setWindSpeed(arr[2]);
                            // 风向
                            qxWeather.setWindDirection(winElement1.equals(winElement2) ? winElement1 : winElement1 + "转" + winElement2);
                            qxWeather.setCreateTime(CmUtil.date2db(null));
                            // 更新数据库
                            qxWeatherMapper.updateByPrimaryKeySelective(qxWeather);
                            this.taskContents = "更新"+dist+" "+wDate+" "+"天气数据成功！";
                        }catch (Exception e){
                            e.printStackTrace();
                            this.taskContents = "更新"+dist+" "+wDate+" "+"天气数据异常！";
                        }
                    }
                    this.taskContents = "日期转换成功！";
                }catch(Exception e){
                    e.printStackTrace();
                    this.taskContents = "日期转换异常！";
                }
            }
        }
        return ReturnT.SUCCESS;
    }

    /**
     * 获取HTML内容
     *
     * @param url
     * @return
     */
    public static Document getHtml(String url, ConstUtil constUtil) {
        Document doc = null;
        try {
            if (constUtil.useProxy) {
                // 设置代理
                Proxy proxy = new Proxy(Proxy.Type.DIRECT.HTTP, new InetSocketAddress(constUtil.proxyId, constUtil.proxyPort));
                doc = Jsoup.connect(url)
                        .proxy(proxy)
                        .userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
                        .timeout(999999999)
                        .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
                        .header("Accept-Encoding", "gzip, deflate")
                        .header("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3")
                        .header("Connection", "keep-alive")
                        //是忽略请求类型
                        .ignoreContentType(true)
                        .get();
            } else {
                doc = Jsoup.connect(url)
                        .userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
                        .timeout(999999999)
                        .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
                        .header("Accept-Encoding", "gzip, deflate")
                        .header("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3")
                        .header("Connection", "keep-alive")
                        //是忽略请求类型
                        .ignoreContentType(true)
                        .get();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return doc;
    }

    public static String openFile( String szFileName ) {
        String ENCODE = "utf-8";
        BufferedReader bis = null;
        try {
            bis = new BufferedReader(new InputStreamReader(new FileInputStream(new File(szFileName)), ENCODE));
            String szContent = "";
            String szTemp;

            while ((szTemp = bis.readLine()) != null) {
                szContent += szTemp + "\n";
            }
            return szContent;
        } catch (Exception e) {
            return "";
        } finally {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void init(){
        logger.info("init");
    }
    public void destroy(){
        logger.info("destory");
    }
}
